package com.hm.system.aspect;

import java.util.List;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.hm.common.model.BaseVo;
import com.hm.common.util.CommonDef.OperationRecord;
import com.hm.common.util.DbDocumentDef;
import com.hm.recycle.mongo.domain.DbDocumentDeleteRecycle;
import com.hm.recycle.mongo.domain.DbDocumentNewRecycle;
import com.hm.recycle.mongo.domain.DbDocumentUpdateRecycle;
import com.hm.recycle.share.service.DbDocumentDeleteRecycleService;
import com.hm.recycle.share.service.DbDocumentNewRecycleService;
import com.hm.recycle.share.service.DbDocumentUpdateRecycleService;
import com.hm.system.auto.SystemProperties;
import com.hm.system.mongo.annotation.RecycleRecordAnnotation;

/**
 * @author shishun.wang
 * @date 2016年5月25日 下午11:27:59
 * @version 1.0
 * @describe
 */
@Aspect
@Component
public class RecycleServiceAspectHandler {
	
	private static Logger logger = LoggerFactory.getLogger(RecycleServiceAspectHandler.class);

	@Autowired
	private SystemProperties systemProperties;

	@Autowired
	private DbDocumentDeleteRecycleService dbDocumentDeleteRecycleService;

	@Autowired
	private DbDocumentUpdateRecycleService dbDocumentUpdateRecycleService;
	
	@Autowired
	private DbDocumentNewRecycleService dbDocumentNewRecycleService;

	@Around("execution(* com.hm.system.service.mongo.**Impl.*(..))")
	public Object process(ProceedingJoinPoint point) throws Throwable {
		if(systemProperties.getLogConfig().isOperation()){
			MethodSignature signature = (MethodSignature) point.getSignature();
			RecycleRecordAnnotation annotation = signature.getMethod().getAnnotation(RecycleRecordAnnotation.class);
			if (null != annotation) {
				OperationRecord record = annotation.value();
				switch (record) {
				case STANDARD_NEW:
					if(systemProperties.getLogConfig().isCreate()){
						newRecycleRecord(annotation, point);
					}
					break;
				case STANDARD_UPDATE:
					if(systemProperties.getLogConfig().isModify()){
						updateRecycleRecord(annotation, point);
					}
					break;
				case STANDARD_DELETE:
					if(systemProperties.getLogConfig().isDel()){
						deleteRecycleRecord(annotation, point);
					}
					break;
				default:
					break;
				}
			}
		}
		return point.proceed();
	}
	
	private void newRecycleRecord(RecycleRecordAnnotation annotation, ProceedingJoinPoint point) {
		BaseVo model = (BaseVo) point.getArgs()[0];
		model.setId(null);
		String operationUser = (String) point.getArgs()[1];
		DbDocumentDef documentDef = annotation.documentDef();
		
		logger.debug("add [" + documentDef.getTagerClass() + "] operation user is " + operationUser);
		
		DbDocumentNewRecycle dbDocumentNewRecycle = new DbDocumentNewRecycle();
		{
			dbDocumentNewRecycle.setCreateUser(operationUser);
			dbDocumentNewRecycle.setDocumentDef(documentDef);
			dbDocumentNewRecycle.setTargetContent(model);
			
			String newLogId = dbDocumentNewRecycleService.addDbDocumentNewRecycle(dbDocumentNewRecycle);
			logger.debug("save DbDocumentNewRecycle successful id is " + newLogId);
		}
		
	}

	private void deleteRecycleRecord(RecycleRecordAnnotation annotation, ProceedingJoinPoint point) {
		BaseVo model = (BaseVo) point.getArgs()[0];
		String operationUser = (String) point.getArgs()[1];
		DbDocumentDef documentDef = annotation.documentDef();
		
		logger.debug("delete [" + documentDef + "] where id is " + model.getId());
		DbDocumentDeleteRecycle dbDocumentRecycle = new DbDocumentDeleteRecycle();
		{
			dbDocumentRecycle.setTargetContent(model);
			dbDocumentRecycle.setDocumentDef(documentDef);
			dbDocumentRecycle.setCreateUser(operationUser);

			String deleteLogId = dbDocumentDeleteRecycleService.addDbDocumentRecycle(dbDocumentRecycle);
			logger.debug("save DbDocumentRecycle successful id is " + deleteLogId);
		}
	}

	private void updateRecycleRecord(RecycleRecordAnnotation annotation, ProceedingJoinPoint point) {
		BaseVo model = (BaseVo) point.getArgs()[0];
		String operationUser = (String) point.getArgs()[1];
		DbDocumentDef documentDef = annotation.documentDef();

		logger.info("update [" + documentDef.getTagerClass() + "] info where id is " + model.getId());
		int version = 1;
		
		List<DbDocumentUpdateRecycle> dbDocumentUpdateRecycles = dbDocumentUpdateRecycleService
				.queryDbDocumentUpdateRecycle(null, model.getId());
		if (!CollectionUtils.isEmpty(dbDocumentUpdateRecycles)) {
			version = dbDocumentUpdateRecycles.get(0).getVersion() + 1;
		}

		DbDocumentUpdateRecycle dbDocumentUpdateRecycle = new DbDocumentUpdateRecycle();
		{
			dbDocumentUpdateRecycle.setState(1);
			dbDocumentUpdateRecycle.setOperationUser(operationUser);
			dbDocumentUpdateRecycle.setDocumentDef(documentDef+"");
			dbDocumentUpdateRecycle.setVersion(version);
			dbDocumentUpdateRecycle.setTargetId(model.getId());
			dbDocumentUpdateRecycle.setTargetContent(model);
			
			String updateLogId = dbDocumentUpdateRecycleService.addDbDocumentUpdateRecycle(dbDocumentUpdateRecycle);
			logger.debug("save DbDocumentUpdateRecycle successful id is " + updateLogId);
		}
	}
}
